/********************************************************************************
*                                                                               *
* kWookaApplicationItemPanel.cpp -- Application Item panel display in the list  *
*                                                                               *
* Copyright (c) Fengren Technology(Guangzhou) Co.LTD. All rights reserved.      *
*                                                                               *
********************************************************************************/


#include "kWookaApplicationItemPanel.hpp"

#include "kWooka_ids.h"
#include "kWookaProjectInfo.hpp"
#include "kWookaExecuteProcess.hpp"
#include "kWookaApplicationListPanel.hpp"
#include "kWooka_frame.hpp"
#include "kWookaApplicationViewPanel.hpp"
#include <wx/xrc/xmlres.h>
#include <wx/html/htmlwin.h>



BEGIN_EVENT_TABLE(kWookaApplicationItemPanel, wxPanel)
    ////Manual Code Start
    EVT_BUTTON(ID_WXBUTTON_STARTAPP, kWookaApplicationItemPanel::OnStartApp)
    EVT_BUTTON(ID_WXBUTTON_STOPAPP, kWookaApplicationItemPanel::OnStopApp)
    EVT_BUTTON(ID_WXBUTTON_DELAPP, kWookaApplicationItemPanel::OnDeleteApp)
    EVT_ENTER_WINDOW(kWookaApplicationItemPanel::OnMouseEnter)
    EVT_LEAVE_WINDOW(kWookaApplicationItemPanel::OnMouseLeave)
    EVT_LEFT_DCLICK(kWookaApplicationItemPanel::OnDblClick)
    EVT_THREAD(EVT_UPDATE_EXECUTE_STATE, kWookaApplicationItemPanel::OnUpdateExecuteState)
    ////Manual Code End
    //EVT_KEY_DOWN(kPosSimpleCheckoutPanel::OnKeyCharEvent)
END_EVENT_TABLE()



kWookaApplicationItemPanel::kWookaApplicationItemPanel(wxWindow *parent, wxWindowID id, const wxString& WXUNUSED(title), const wxPoint &position, const wxSize& size, long style)
: wxPanel(parent, id, position, size, style)
{
    m_executor = NULL;
    m_project = NULL;
    m_backgroundColor = COLOURE_LEAVE_WINDOW;
    CreateGUIControls();
}

kWookaApplicationItemPanel::~kWookaApplicationItemPanel()
{
    wxLogDebug(wxT("kWookaApplicationItemPanel destroyed."));
}

void kWookaApplicationItemPanel::CreateGUIControls()
{
    //Do not add custom code between
    //GUI Items Creation Start and GUI Items Creation End
    //wxDev-C++ designer will remove them.
    //Add the custom code before or after the blocks
    ////GUI Items Creation Start

    CreateContentPanel();
    Center();
    ////GUI Items Creation End
}

/**
    Create the App's Content panel
    
 */
void kWookaApplicationItemPanel::CreateContentPanel() {
    wxBitmap prefsBmp = wxXmlResource::Get()->LoadBitmap(wxT("IDB_ICON_SPRING"));// wxBitmap(_T("images/kpos_prefs_icon.png"), wxBITMAP_TYPE_PNG);
    
    wxBitmap startNBmp = wxXmlResource::Get()->LoadBitmap(wxT("IDB_APP_START_N"));
    wxBitmap startSBmp = wxXmlResource::Get()->LoadBitmap(wxT("IDB_APP_START_S"));
    wxBitmap stopNBmp = wxXmlResource::Get()->LoadBitmap(wxT("IDB_APP_STOP_N"));
    wxBitmap stopSBmp = wxXmlResource::Get()->LoadBitmap(wxT("IDB_APP_STOP_S"));


    wxStaticBitmap* bmpView = new wxStaticBitmap(this, wxID_ANY, prefsBmp);

    kWookaAppName = new kWoocaStaticText(this, ID_WXSTATICTEXT_APP_NAME, wxT("APPLICATION NAME"), wxPoint(24, 18), wxSize(200, 24), wxST_ELLIPSIZE_END, _T("WxStaticAppName"));
    kWookaAppDesc = new kWoocaStaticText(this, ID_WXSTATICTEXT_APP_DESC, wxT("Multi-line description"), wxPoint(24, 18), wxSize(200, 60), 0, _T("WxStaticAppDesc"));
    kWookaAppState = new kWoocaStaticText(this, ID_WXSTATICTEXT_APP_STATE, _("Unknow"), wxPoint(24, 18), wxSize(200, 20), wxST_ELLIPSIZE_START, _T("WxStaticAppState"));
    WxBtnRestartApp = new wxBitmapButton();
    WxBtnRestartApp->SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
    WxBtnRestartApp->Create(this, ID_WXBUTTON_STARTAPP, wxArtProvider::GetBitmap(wxART_GO_FORWARD), wxPoint(500, 270), wxSize(24, 24), 0, wxDefaultValidator, _T("WxButton2"));

    WxBtnRestartApp->SetBitmap(startNBmp);
    WxBtnRestartApp->SetBitmapFocus(startSBmp);
    WxBtnRestartApp->SetBitmapHover(startSBmp);

    WxBtnStopApp = new wxBitmapButton(this, ID_WXBUTTON_STOPAPP, wxArtProvider::GetBitmap(wxART_GO_HOME), wxPoint(500, 270), wxSize(24, 24), wxBG_STYLE_TRANSPARENT, wxDefaultValidator, _T("WxButton5"));
    WxBtnStopApp->SetBitmap(stopNBmp);
    WxBtnStopApp->SetBitmapFocus(stopSBmp);
    WxBtnStopApp->SetBitmapHover(stopSBmp);

    // WxBtnDeleteApp = new wxBitmapButton(this, ID_WXBUTTON_DELAPP, wxXmlResource::Get()->LoadBitmap(wxT("IDB_APP_STASH")), wxPoint(500, 270), wxSize(48, 48), wxBG_STYLE_TRANSPARENT, wxDefaultValidator, _T("WxButton3"));
    WxBtnDeleteApp = new wxBitmapButton(this, ID_WXBUTTON_DELAPP, wxArtProvider::GetBitmap(wxART_DELETE), wxPoint(500, 270), wxSize(24, 24), wxBG_STYLE_TRANSPARENT, wxDefaultValidator, _T("WxButton3"));
    // wxART_DELETE
    //kWookaAppName->Disable();
    kWookaAppState->Disable();

    kWookaAppName->SetForegroundColour(COLOURE_MAJOR_WHITE);
    kWookaAppDesc->SetForegroundColour(COLOURE_MINOR_WHITE);
    kWookaAppState->SetForegroundColour(COLOURE_MINOR_WHITE);

    wxFont ft = kWookaAppName->GetFont();
    ft.SetPointSize(12);
    ft.SetWeight(200);
    kWookaAppName->SetFont(ft);

    // kWookaAppDesc->SetForegroundColour((215, 252, 3, 255));
    /*
    kWookaAppName->Connect(ID_WXSTATICTEXT_APP_NAME, wxEVT_ENTER_WINDOW, wxMouseEventHandler(kWookaApplicationItemPanel::OnMouseEnter), NULL, this);
    kWookaAppName->Connect(ID_WXSTATICTEXT_APP_NAME, wxEVT_LEAVE_WINDOW, wxMouseEventHandler(kWookaApplicationItemPanel::OnMouseLeave), NULL, this);
    kWookaAppName->Connect(ID_WXSTATICTEXT_APP_NAME, wxEVT_LEFT_DCLICK, wxMouseEventHandler(kWookaApplicationItemPanel::OnDblClick), NULL, this);
    
    kWookaAppDesc->Connect(ID_WXSTATICTEXT_APP_DESC, wxEVT_ENTER_WINDOW, wxMouseEventHandler(kWookaApplicationItemPanel::OnMouseEnter), NULL, this);
    kWookaAppDesc->Connect(ID_WXSTATICTEXT_APP_DESC, wxEVT_LEAVE_WINDOW, wxMouseEventHandler(kWookaApplicationItemPanel::OnMouseLeave), NULL, this);
    kWookaAppDesc->Connect(ID_WXSTATICTEXT_APP_DESC, wxEVT_LEFT_DCLICK, wxMouseEventHandler(kWookaApplicationItemPanel::OnDblClick), NULL, this);
    */

    bmpView->Disable();

    WxBtnStopApp->SetTransparent(1);
    WxBtnRestartApp->SetTransparent(1);
    WxBtnDeleteApp->SetTransparent(1);
    WxBtnRestartApp->SetToolTip(_("Start the application"));
    WxBtnStopApp->SetToolTip(_("Stop the application"));
    WxBtnDeleteApp->SetToolTip(_("Delete the application"));

    wxBoxSizer* wxHorzSizer = new wxBoxSizer(wxHORIZONTAL);

    wxBoxSizer* wxBarcodeBoxSizer = new wxBoxSizer(wxVERTICAL);
    wxBarcodeBoxSizer->Add(kWookaAppName, 0, wxEXPAND | wxTOP, 0);
    wxBarcodeBoxSizer->Add(kWookaAppDesc, 1, wxEXPAND | wxALL, 0);
    wxBarcodeBoxSizer->Add(kWookaAppState, 0, wxEXPAND | wxBOTTOM, 0);
    
    //WxBtnRestartApp->SetBitmapCurrent(wxXmlResource::Get()->LoadBitmap(wxT("IDB_APP_START")));
    //WxBtnStopApp->SetBitmapCurrent(wxXmlResource::Get()->LoadBitmap(wxT("IDB_APP_STOP")));
    //WxBtnDeleteApp->SetBitmapCurrent(wxXmlResource::Get()->LoadBitmap(wxT("IDB_APP_STASH")));

    wxHorzSizer->Add(bmpView, 0, wxSTRETCH_NOT | wxALIGN_CENTER_VERTICAL | wxLEFT, 5);
    wxHorzSizer->Add(wxBarcodeBoxSizer, 1, wxEXPAND | wxALL, 5);
    wxHorzSizer->Add(WxBtnRestartApp, 0, wxSTRETCH_NOT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
    wxHorzSizer->Add(WxBtnStopApp, 0, wxSTRETCH_NOT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
    wxHorzSizer->Add(WxBtnDeleteApp, 0, wxSTRETCH_NOT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
    UpdateButtonState();
    this->SetSizerAndFit(wxHorzSizer);
    this->Layout();
}

void kWookaApplicationItemPanel::OnKeyCharEvent(wxKeyEvent& event){
    if (event.GetKeyCode() == WXK_RETURN){
    }
}


void kWookaApplicationItemPanel::SetAppItemInfo(kWookaAppItemInfo* item) {
    m_item = item;
    if (m_item != NULL) {
        kWookaAppName->SetLabelText(m_item->name + "\t" + m_item->version);
        kWookaAppDesc->SetLabelText(m_item->source);
        
        kWookaAppName->Refresh();
        kWookaAppDesc->Refresh();
    }
}

void kWookaApplicationItemPanel::OnStartApp(wxCommandEvent& WXUNUSED(event)) {
    _CrtMemCheckpoint(&s1);
    m_executor = this->GetProjectInfo()->runtime->GetExecutor(m_item->id);
    if (!m_executor->IsStarted()) {
        m_executor->Start();
        m_executor->AttachListPanel(this->GetListPanel());
        UpdateButtonState();
    }
    
}

void kWookaApplicationItemPanel::SetListPanel(kWookaApplicationListPanel* lp) {
    m_listpanel = lp;
}

kWookaApplicationListPanel* kWookaApplicationItemPanel::GetListPanel() {
    return m_listpanel;
}

void kWookaApplicationItemPanel::OnStopApp(wxCommandEvent& WXUNUSED(event)) {
    m_executor = this->GetProjectInfo()->runtime->GetExecutor(m_item->id);
    if (m_executor->IsStarted()) {
        m_executor->Stop();
        UpdateButtonState();
    }
    _CrtMemCheckpoint(&s2);
    _CrtMemDumpStatistics(&s1);
    _CrtMemDumpStatistics(&s2);
    _CrtMemDifference(&s3, &s1, &s2);
    _CrtMemDumpStatistics(&s3);
}

void kWookaApplicationItemPanel::OnDeleteApp(wxCommandEvent& WXUNUSED(event)) {
    if (this->GetProjectInfo() != NULL) {
        if (wxMessageBox(_("Do you want to delete this application from this project?"), _("kWooca"), wxYES_NO) == wxYES) {
            this->GetProjectInfo()->DeleteAppItem(this->m_item);
            this->GetListPanel()->RemoveItemPanel(this);
        }
    }
}

void kWookaApplicationItemPanel::OnMouseEnter(wxMouseEvent& event) {
    if (event.GetId() == ID_WXSTATICTEXT_APP_NAME || event.GetId() == ID_WXSTATICTEXT_APP_DESC) {
        this->SetBackgroundColour(COLOURE_ENTER_WINDOW);
        this->Refresh();
        this->Layout();
    } else if (this->HitTest(event.GetX(), event.GetY()) == wxHitTest::wxHT_WINDOW_INSIDE) {
        this->SetBackgroundColour(COLOURE_ENTER_WINDOW);
        this->Refresh();
        this->Layout();
    }
}

void kWookaApplicationItemPanel::OnMouseLeave(wxMouseEvent& event) {
    if (event.GetId() == ID_WXSTATICTEXT_APP_NAME || event.GetId() == ID_WXSTATICTEXT_APP_DESC) {
        this->SetBackgroundColour(m_backgroundColor);
        this->Refresh();
        this->Layout();
    } else if (this->HitTest(event.GetX(), event.GetY()) == wxHitTest::wxHT_WINDOW_OUTSIDE) {
        this->SetBackgroundColour(m_backgroundColor);
        this->Refresh();
        this->Layout();
    }
}

void kWookaApplicationItemPanel::OnDblClick(wxMouseEvent& event) {
    if (event.GetId() == ID_WXSTATICTEXT_APP_NAME || event.GetId() == ID_WXSTATICTEXT_APP_DESC
        || this->HitTest(event.GetX(), event.GetY()) == wxHitTest::wxHT_WINDOW_INSIDE) {
        this->Layout();
        GetListPanel()->GetWookaFrame()->GetViewPanel()->UpdateAppItem(GetListPanel()->GetWookaFrame()->GetProjectInfo(), m_item);
        GetListPanel()->UpdateSelectItem(this);
        SetSelected(true);
        this->Refresh();
    }
}

void kWookaApplicationItemPanel::OnUpdateExecuteState(wxThreadEvent& event) {
    this->UpdateButtonState();
    event.UnRef();
}


void kWookaApplicationItemPanel::UpdateButtonState() {
    this->WxBtnStopApp->Show(false);
    this->WxBtnRestartApp->Show(true);
    if (this->GetProjectInfo() != NULL) {
        m_executor = this->GetProjectInfo()->runtime->GetExecutor(m_item->id);
        if (m_executor != NULL) {
            if (m_executor->IsStarted()) {
                this->WxBtnStopApp->Show(true);
                this->WxBtnRestartApp->Show(false);
            }
            else {
                this->WxBtnStopApp->Show(false);
                this->WxBtnRestartApp->Show(true);
            }
            switch (m_executor->GetExecuteState())
            {
            case NoStarted:
                this->kWookaAppState->SetLabelText(_("Not Started"));
                break;
            case Starting:
                this->kWookaAppState->SetLabelText(_("Starting"));
                break;
            case Started:
                this->kWookaAppState->SetLabelText(_("Ready"));
                break;
            case Ended:
                this->kWookaAppState->SetLabelText(_("Ended"));
                break;
            default:
                this->kWookaAppState->SetLabelText(_("Unknow"));
                break;
            } 
            
        }
    }
}

void kWookaApplicationItemPanel::UpdateState() {
    if (this->IsSelected()) {
        m_backgroundColor = COLOURE_SELECTED;
    }
    else { 
        m_backgroundColor = COLOURE_LEAVE_WINDOW;
    }
    SetBackgroundColour(m_backgroundColor);
}